<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="pragma" content="no-cache">
	<meta name="googlebot" content="noarchive">
	<meta name="robots" content="none">
	<meta name="author" content="Jeff Genovy (jgen)">
	<meta name="version" content="0.1">
	<meta name="description" content="A remote interface for Urban Terror 4.1 servers">
	<title>Remote Interface</title>
<!--
  Remote Interface (for Urban Terror)
  Author: Jeff Genovy (jgen)
  Date: August 2009
  [BSD Licensed]

 This interface makes use of Yahoo's User Interface Library (YUI),
 available under a BSD license from:
 http://developer.yahoo.com/yui/
-->

<!-- Individual YUI CSS files --> 
<link rel="stylesheet" type="text/css" href="resource/reset/reset_base.css">
<link rel="stylesheet" type="text/css" href="resource/skins/sam/skin.css">

<!-- All the required YUI libraries rolled into one file -->
<script type="text/javascript" src="resource/js/YUI_library_combo.js"></script> 


<!-- IP Address conversion routines by jgen -->
<script type="text/javascript" src="resource/js/ip.js"></script>


<style type="text/css">
	html	{ background-color: #90CCDB; }
	body	{ margin:0; padding:0; }
	
	form { padding:0.3em; }
	
	form label {
		display:block;
		float:left;
		width:35%;
		clear:left;
	}
	fieldset,
	fieldset div {
		margin: 0.3em;
		padding: 0.5em;
		font-size:100%;
		border: 2px groove #ccc;
	}
	fieldset legend {
		padding-left: 5px;
		padding-right: 5px;
		padding-bottom:0;
		padding-top:0;
	}
	form fieldset legend.config {
		font-size: 107%;
		margin: 0.3em;
	}
	form fieldset input {
		margin: 2px;
	}


	p.error_small {
		font-size:85%; margin-left:2em;
	}
	p.error_title {
		/* OrangeRed, bold */
		font-size:107%; font-weight:bold; color:#FF4500; padding:1em; margin-bottom:1.5em;
	}
	p.about_title {
		font-size:114%; font-weight:bold; font-family:Courier; color:#000000;
	}
	p.about_version {
		font-size:85%; font-family:Courier; margin-left:2em;
	}
	p.status_ok {
		/* Green */
		font-size:107%; margin-top:1em; text-align:center; color:#009900;
	}
	p.status_err {
		/* OrangeRed  */
		font-size:107%; margin-top:1em; text-align:center; color:#FF4500;
	}
	table.server_info { border-style: none; border: 0px; width: 350px; text-align: left; padding: 0px; }
	table.server_info td { border: 0px; padding: 0.5em; }
	table.server_info td.name { font-weight: bold; }

	div.search_pager {
		margin-top: 0 !important;
		margin-left: 5px !important;
		margin-bottom: 5px;
		font-size: 100%;
	}
	div.search_pager select {
		font-size: 85%;
	}
	
	#mainmenubar {
		font-size: 100%;
	}
</style>

<script type="text/javascript">
<!--

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

/* Remote Interface for Urban Terror by jgen */

YAHOO.namespace("remoteInterface");

var ri = YAHOO.remoteInterface;

ri.search_panels = new Array();

ri.init = function() {


var sUrlBase = 'interface.php';

var bColorizeNames = false;
var bConvertDuration = true;
var bHideIds = true;
var bHideNumericIps = true;


var aItemData = [
	{
		text: "Main",
		submenu: {
			id: "mainmenuitem",
			itemdata: [
				{ text: "Status", id: "mainstatus", selected: true },
				{ 
					text: "Configure",
					id: "configuremenuitem",
					submenu: {
						id: "configmenu",
						itemdata: [
							{ text: "RCON password", id: 'serverpassword' },
							{ text: "Server Setup", id: 'serverconfig' },
							{ text: "Database Setup", id: 'databaseconfig' }
						]
					}
				},
				{ text: "Options", id: "options" }
			]
		}
	},
	{
		text: "Server",
		submenu: {
			id: "servermenuitem",
			itemdata: [
				{ text: "Current Players", id: "currentplayers", helptext: "Alt + C", selected: true },
				[
					{ text: "Search by Name", id: 'searchname', helptext:"Alt + Z" },
					{ text: "Search by IP", id: 'searchip', helptext:"Alt + X" }
				]
			]
		}
	},
	{
		text: "Help",
		submenu: {
		id: "helpmenuitem",
			itemdata: [
				{ text: "Help", id: "help_reference" },
				{ text: "About", id: "about" }
			]
		}
	}
];

	var oMainMenu = new YAHOO.widget.MenuBar("mainmenubar", { position: "static", lazyload: false, itemdata: aItemData });
	oMainMenu.render(document.body);

	
	
	// Generic 'Alert' Dialog
	var alert_panel = new YAHOO.widget.SimpleDialog('alert', {
		fixedcenter: true,
		visible: false,
		modal: true,
		width: '300px',
		constraintoviewport: true, 
		icon: YAHOO.widget.SimpleDialog.ICON_WARN,
	//	keylisteners: esckey,
		buttons: [
			{ text: 'OK', handler: function() { alert_panel.hide();	}, isDefault: true }
		]
	});
	alert_panel.setHeader('Alert');
	alert_panel.setBody('...');
	alert_panel.render(document.body);

	//Create a namepaced alert method
	ri.alert = function(str) {
		alert_panel.setBody(str);
		alert_panel.cfg.setProperty('icon', YAHOO.widget.SimpleDialog.ICON_WARN);
		alert_panel.bringToTop();
		alert_panel.show();
	};
	
	
	var oAboutPanel = new YAHOO.widget.Panel("about_info", {
			width:"350px",
			height:"150px",
			visible:false,
			draggable:true,
			dragOnly:true,
			close:true,
			underlay:"Shadow",
			fixedcenter:true,
			constraintoviewport:true,
			zIndex: 5
		} );
	oAboutPanel.render(document.body);

	var oHelpPanel = new YAHOO.widget.Panel("help_panel", {

			visible:false,
			draggable:true,
			dragOnly:true,
			close:true,
			underlay:"none",
			fixedcenter:true,
			constraintoviewport:true,
			zIndex: 5
		} );
	oHelpPanel.render(document.body);

	
	var oOptionsPanel = new YAHOO.widget.Dialog("options_panel", {
			width:'325px',
			height:'230px',
			visible:false,
			draggable:true,
			dragOnly:true,
			close:true,
			underlay:"none",
			fixedcenter:true,
			constraintoviewport:true,
			zIndex: 3,
			buttons: [ { text: "Close", handler: function(o){ this.hide(); } } ]
		} );
	oOptionsPanel.render(document.body);
	
	
	
	var fSearchRedrawTables = function() {
		for (var i =0; i < ri.search_panels.length; i++) {
			if (ri.search_panels[i].oSearchTable) {
				ri.search_panels[i].oSearchTable.render();
			}
		}
	};

	var fColorNames = function(o) {
		if (this) {
			bColorizeNames = !bColorizeNames;
			fSearchRedrawTables();
		}
	};
	var fConvertDuration = function(o) {
		if (this) {
			bConvertDuration = !bConvertDuration;
			fSearchRedrawTables();
		}
	};
	var fShowIds = function(o) {
		if (this) {
			bHideIds = !bHideIds;

			for (var i=0; i < ri.search_panels.length; i++) {
				if (ri.search_panels[i].oSearchTable) {
					var column1 = ri.search_panels[i].oSearchTable.getColumn('player_ids');
					var column2 = ri.search_panels[i].oSearchTable.getColumn('player_id');
					
					if (column1) {
						if (bHideIds) {
							ri.search_panels[i].oSearchTable.hideColumn(column1);
						} else {
							ri.search_panels[i].oSearchTable.showColumn(column1);
						}
					}
					if (column2) {
						if (bHideIds) {
							ri.search_panels[i].oSearchTable.hideColumn(column2);
						} else {
							ri.search_panels[i].oSearchTable.showColumn(column2);
						}
					}
				}
			}
			
			for (var k=0; k < aSearchIpTableColums.length; k++) {
				if (aSearchIpTableColums[k].key == 'player_ids') {
					aSearchIpTableColums[k].hidden = bHideIds;
				}
			}

			for (var k=0; k < aSearchNameTableColums.length; k++) {
				if (aSearchNameTableColums[k].key == 'player_id') {
					aSearchNameTableColums[k].hidden = bHideIds;
				}
			}

			fSearchRedrawTables();
		}
	};
	var fShowNumericIps = function(o) {
		if (this) {
			bHideNumericIps = !bHideNumericIps;
			
			for (var i=0; i < ri.search_panels.length; i++) {
				if (ri.search_panels[i].oSearchTable) {
					var column1 = ri.search_panels[i].oSearchTable.getColumn('ip');
					
					if (column1) {
						if (bHideNumericIps) {
							ri.search_panels[i].oSearchTable.hideColumn(column1);
						} else {
							ri.search_panels[i].oSearchTable.showColumn(column1);
						}
					}
				}
			}
			
			for (var k=0; k < aSearchIpTableColums.length; k++) {
				if (aSearchIpTableColums[k].key == 'ip') {
					aSearchIpTableColums[k].hidden = bHideNumericIps;
				}
			}
			
			fSearchRedrawTables();
		}
	};
	
	
	var oStatusPanel = new YAHOO.widget.Panel("status_panel", {
			width:"430px",
			visible:false,
			draggable:true,
			dragOnly:true,
			close:true,
			underlay:"shadow",
			constraintoviewport:true,
			zIndex: 2
		} );
	oStatusPanel.setHeader("Status");
	oStatusPanel.setBody("This panel contains information on the backend and the server.<br><br><div id='status_tabs'><\/div>");
	oStatusPanel.setFooter("<div id='status_refresh'><\/div>");
	oStatusPanel.render(document.body);

	var oTabView = new YAHOO.widget.TabView();
	oTabView.addTab( new YAHOO.widget.Tab({ label: 'Backend', content: '<div id="status_backend_tab"><\/div>', active: true }) );
	//oTabView.addTab( new YAHOO.widget.Tab({ label: 'Log Files', content: '<div id="backend_log_tab"><\/div>' }) );
	oTabView.addTab( new YAHOO.widget.Tab({ label: 'Server', content: '<div id="status_server_tab"><\/div>' }) );
	oTabView.appendTo("status_tabs");

	var fUpdateStatus = function() {
		var back_tab = document.getElementById('status_backend_tab');
		var serv_tab = document.getElementById('status_server_tab');
		var sQuery = sUrlBase + '?status';
		var tmp_str = '';
				
		var hdl_successful = function(o) {
			if (o.responseText !== undefined) {
				try { var status_data = YAHOO.lang.JSON.parse(o.responseText); }
				catch (e) { ri.alert('An error occured while parsing the reply from the server...'); }
				
				var status = parseInt(status_data.backend.backend_status, 10);
				var msg = '';
				
				if (status !== undefined) {
					switch (status) {
						case 2:
							msg = 'Backend reports OK status.';	break;
						case 1:
							msg = 'Backend reports last shutdown was unclean.';	break;
						case 0:
							msg = 'The backend is not running.'; break;
						case -1:
							msg = 'Backend error: Could not open a socket.'; break;
						case -2:
							msg = 'Backend error: Could not connect to external address.'; break;
						case -3:
							msg = 'Backend error: Could not send message to server.'; break;
						case -4:
							msg = 'Backend error: Error recieving data from server.'; break;
						case -5:
							msg = 'Backend reports that the Server did not respond - request timed out.'; break;
						case -6:
							msg = 'Backend error: Could not close the socket.'; break;
						case -10:
							msg = 'Backend reports: Bad rcon password.'; break;
						case -11:
							msg = 'Backend reports: The server did not recognize the command.'; break;
						case -12:
							msg = 'Backend reports: No rcon password set yet.'; break;
						case -13:
							msg = 'Backend reports: Server config is missing or incorrect.'; break;
						default:
							msg = 'Unknown status value.';
					}
					
					if (status > 1) {
						back_tab.innerHTML = "<p class='status_ok'>" + msg + "<\/p>";
					} else {
						back_tab.innerHTML = "<p class='status_err'>" + msg + "<\/p>";
					}
				}
				if (status_data.server !== undefined) {
					var name = status_data.server.name;
					var map = status_data.server.current_map;
					var pw = status_data.server.rcon_pw;

					var ip = long2ip(parseInt(status_data.server.ip, 10));
					var port = parseInt(status_data.server.port, 10);
					var t_delay = parseInt(status_data.server.timeout_delay, 10);
					var t_wait = parseInt(status_data.server.timeout_wait_delay, 10);
					var timeouts = parseInt(status_data.server.timeouts, 10);
					var timeout_last = parseInt(status_data.server.timeout_last, 10);
					var timeout_Date = new Date(timeout_last * 1000);

					var srv_pw = document.getElementById('srv_rcon_pw');
					if (srv_pw && srv_pw.value == '') { srv_pw.value = pw; }

					var srv_port = document.getElementById('srv_port');
					if (srv_port && srv_port.value == '') { srv_port.value = port; }

					var srv_t_delay = document.getElementById('srv_timeout');
					if (srv_t_delay && srv_t_delay.value == '') { srv_t_delay.value = t_delay; }

					var srv_t_wait = document.getElementById('srv_timeout_wait');
					if (srv_t_wait && srv_t_wait.value == '') { srv_t_wait.value = t_wait; }

					var srv_ip = document.getElementById('srv_ip_address');
					if (srv_ip && srv_ip.value == '') { srv_ip.value = ip; }


					tmp_str = "<table class='server_info'><tbody>";
					tmp_str += "<tr><td>Server Name<\/td><td class='name'>"+ name +"<\/td><\/tr>";
					tmp_str += "<tr><td>IP Address<\/td><td>"+ ip +"<\/td><\/tr>";
					tmp_str += "<tr><td>Port<\/td><td>"+ port +"<\/td><\/tr>";
					tmp_str += "<tr><td>Map<\/td><td>"+ map +"<\/td><\/tr>";
					tmp_str += "<tr><td>Last Timeout<\/td><td>"+ timeout_Date.toGMTString() +"<\/td><\/tr>";
					tmp_str += "<\/tbody><\/table>";

					serv_tab.innerHTML = tmp_str;

					return true;
				}
			}
			ri.alert('The server response was invalid.');
			return false;
		};
		
		var hdl_failure = function(o) {
			if (o.responseText !== undefined) {
				tmp_str = "<p class='error_title'>An error occured while communcating to the server<\/p>";
				tmp_str += "<p class='error_small'><u>Details:<\/u><br>";
				tmp_str += "Transaction id: "+ o.tId +"<br>HTTP status: "+ o.status +"<br>";
				tmp_str += "Status code message: "+ o.statusText +"<\/p>";
				back_tab.innerHTML = tmp_str;
			} else {
				ri.alert('The server response was invalid.');
			}
		};
		
		var status_callback = {
			success: hdl_successful,
			failure: hdl_failure,
			argument: null,
			timeout: 1500		
		};
		
		var request = YAHOO.util.Connect.asyncRequest('GET', sQuery, status_callback, null);
	};
	
	var oStatusRefresh = new YAHOO.widget.Button({ label:"Refresh", id:"statusupdate", container:"status_refresh" });
	oStatusRefresh.on("click", fUpdateStatus);
	
	
		
	// Generic 'Cancel' handler, simply hides the dialog box
	var handleGenericCancel = function(o) { this.cancel(); };

	
	var handleServerCfgApply = function() {
		var ans = confirm("Are you sure you want to change the server config?");
		if ( ans ) {
			this.submit();
		} else {
			this.cancel();
		}
	};
	var oServerCfgDlg = new YAHOO.widget.Dialog("server_config",
			{	width: "325px",
				fixedcenter: true,
				visible:false,
				draggable:true,
				dragOnly:true,
				close:true,
				underlay:"Shadow",
				zIndex: 3,
				constraintoviewport: true,
				buttons: [ { text: "Apply", handler: handleServerCfgApply }, { text: "Cancel", handler: handleGenericCancel, isDefault: true } ]
			} );
	oServerCfgDlg.validate = function() {
		var data = this.getData();
		if (data.ip == "" ) {
			alert("Please enter an IP address.");
		} else if (data.port == "") {
			alert("Please enter a Port number.");
		} else if (data.timeout_delay == "") {
			alert("Please enter a timeout delay.");
		} else if (data.timeout_wait == "") {
			alert("Please enter a time to wait between timeouts.");
		} else {
			return true;
		}
		return false;
	};
	oServerCfgDlg.callback.success = function(o) {
		ri.alert("Successfully updated the server config.");
		alert( YAHOO.lang.dump(o) );
	};
	oServerCfgDlg.callback.failure = function(o) {
		ri.alert("Failed to update the server config.");
		alert( YAHOO.lang.dump(o) );
	};
	oServerCfgDlg.render(document.body);


	var oServerRconPwDlg = new YAHOO.widget.Dialog("server_rcon_pw",
			{	width: "305px",
				fixedcenter: true,
				visible:false,
				draggable:true,
				dragOnly:true,
				close:true,
				underlay:"Shadow",
				zIndex: 3,
				constraintoviewport: true,
				buttons: [ { text: "Apply", handler:function(){this.submit();} }, { text: "Cancel", handler: handleGenericCancel, isDefault: true } ]
			} );
	oServerRconPwDlg.validate = function() {
		var data = this.getData();
		if (data.pw == "") {
			alert("Please enter a password.");
			return false;
		} else {
			return true;
		}
	};
	oServerRconPwDlg.callback.success = function(o) {
		ri.alert("Updated the rcon password.");
		alert( YAHOO.lang.dump(o) );
	};
	oServerRconPwDlg.callback.failure = function(o) {
		ri.alert("Failed to update the rcon password");
		alert( YAHOO.lang.dump(o) );
	};
	oServerRconPwDlg.render(document.body);

	
	var fSearchGarbageCollect = function() {
		for (var i =0; i < ri.search_panels.length; i++) {
			if (ri.search_panels[i] && ri.search_panels[i].cfg.config.visible.value == false) {
				if (ri.search_panels[i].oSearchTable) {
					ri.search_panels[i].oSearchTable.destroy();
				}
				ri.search_panels[i].destroy();
				ri.search_panels.remove(i);
				i--;
			}
		}
	};
	

	var fNewSearchPanel = function(o) {
		if (o && o.responseText !== undefined) {
		
			try { var search_data = YAHOO.lang.JSON.parse(o.responseText); }
			catch (e) { ri.alert('An error occured while parsing the reply from the server...'); }
		
			var id_name = "search_panel_" + o.tId;
			var id_table = "search_table_" + o.tId;
			var id_page = "search_paginator_" + o.tId;
		
			var temp = new YAHOO.widget.Panel( id_name, {
					visible:false,
					draggable:true,
					dragOnly:true,
					close:true,
					underlay:"Shadow",
					constraintoviewport:false,
					zIndex:1
				} );
			temp.setHeader("Search Results");
			temp.setBody("<div class='search_pager' id='"+ id_page +"'><\/div><div id='"+ id_table +"'><\/div>");
			temp.render( document.getElementById("search_results_container") );

			temp.oSearchPaginator = new YAHOO.widget.Paginator({
					containers: id_page,
					rowsPerPage:	15,
					rowsPerPageOptions : [10,15,25,30,40,50],
					alwaysVisible: false,
					template: '<b>{FirstPageLink} {PreviousPageLink}<\/b>{CurrentPageReport}<b>{NextPageLink} {LastPageLink}<\/b> {RowsPerPageDropdown}per page',
					firstPageLinkLabel: "<<",
					lastPageLinkLabel: ">>",
					nextPageLinkLabel: ">",
					previousPageLinkLabel: "<",
				});
			
			var oSearchNameTableConfigs = {
					sortedBy: { key:'player_id', dir: YAHOO.widget.DataTable.CLASS_ASC },
					selectionMode: 'single',
					paginator: temp.oSearchPaginator
			};
			var oSearchIpTableConfigs = {
					sortedBy: { key:'ip', dir: YAHOO.widget.DataTable.CLASS_ASC },
					selectionMode: 'single',
					paginator: temp.oSearchPaginator
			};
			
			temp.oSearchDataSource = new YAHOO.util.LocalDataSource( o.responseText );
			temp.oSearchDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
			
			if (search_data.type == "name") {
				temp.oSearchDataSource.responseSchema = oSearchNameSchema;
				temp.oSearchTable = new YAHOO.widget.DataTable( id_table, aSearchNameTableColums, temp.oSearchDataSource, oSearchNameTableConfigs);
			} else if (search_data.type == "ip") {
				temp.oSearchDataSource.responseSchema = oSearchIpSchema;
				temp.oSearchTable = new YAHOO.widget.DataTable( id_table, aSearchIpTableColums, temp.oSearchDataSource, oSearchIpTableConfigs);
			} else {
				ri.alert('The server response is the wrong type.');
			}
				
			ri.search_panels.push(temp);
			temp.show();
		} else {
			ri.alert('The server response was invalid.');
		}
		fSearchGarbageCollect();
	};

	/* Variables used by the Search Panel Tables */
	var formatNameColors = function(elCell, oRecord, oColumn, oData) {
		var list = oData;
		if (bColorizeNames) {
			list = list.replace(/\^0/g, "<font color='#000000'>");
			list = list.replace(/\^1/g, "<font color='#FF0000'>");
			list = list.replace(/\^2/g, "<font color='#00FF00'>");
			list = list.replace(/\^3/g, "<font color='#FFFF00'>");
			list = list.replace(/\^4/g, "<font color='#0000FF'>");
			list = list.replace(/\^5/g, "<font color='#00FFFF'>");
			list = list.replace(/\^6/g, "<font color='#FF00FF'>");
			list = list.replace(/\^7/g, "<font color='#FFFFFF'>");
		}
		elCell.innerHTML = list;
	};
	var formatDuration = function(elCell, oRecord, oColumn, oData) {
		if (bConvertDuration) {
			if (oData > 86400) {
				var days = Math.floor(oData / 86400);
				var hr = Math.floor((oData % 86400) / 3600);
				var min = Math.floor((oData % 3600) / 60);
				var sec = oData % 60;
			
				elCell.innerHTML = days + ' d ' + hr + ' hr ' + min + ' min ' + sec + ' sec';
			} else if (oData > 3600) {
				var hr = Math.floor(oData / 3600);
				var min = Math.floor((oData % 3600) / 60);
				var sec = oData % 60;
			
				elCell.innerHTML = hr + ' hr ' + min + ' min ' + sec + ' sec';
			} else if (oData > 60) {
				var min = Math.floor(oData / 60);
				var sec = oData % 60;
				
				elCell.innerHTML = min + ' min ' + sec + ' sec';
			} else {
				elCell.innerHTML = oData + ' sec';
			}
		} else {
			elCell.innerHTML = oData;
		}
	};
	var formatList = function(elCell, oRecord, oColumn, oData) {
		if (oData) {
			var str = oData.toString();
			var list = str.split(',');
			str = '';
			for (var i=0; i < list.length; i++) {
				str = str + list[i] + ', ';
			}
			elCell.innerHTML = str.substring(0, str.length - 2);
		}
	};
	var aSearchNameTableColums = [
			{ key:"player_id", label:"ID", sortable:true, hidden:bHideIds },
			{ key:"name", label:"Name", formatter: formatNameColors },
			{ key:"ips", label:"IP Addresses", formatter: formatList },
			{ key:"guids", label:"GUIDs", formatter: formatList },
			{ key:"duration", label:"Duration", formatter: formatDuration, sortable:true }
		];
	var oSearchNameSchema = {
			resultsList: 'data',
			fields: [
				{key:'player_id', parser:'number'},
				{key:'name'},
				{key:'ips' },
				{key:'guids'},
				{key:'duration', parser:'number'}
			],
			metaFields: {
				rows: 'rows'
			}
		};
	var formatNameList = function(elCell, oRecord, oColumn, oData) {
		var list = oData.slice(1, oData.length - 1);
		if (bColorizeNames) {
			//list = '<span style="background-color: #AAAAAA;">' + list;
			list = list.replace(/\^0/g, "<font color='#000000'>");
			list = list.replace(/","/g, "<font color='#000000'>\",\"");
			list = list.replace(/"$/, "<font color='#000000'>\"");
			list = list.replace(/\^1/g, "<font color='#FF0000'>");
			list = list.replace(/\^2/g, "<font color='#00FF00'>");
			list = list.replace(/\^3/g, "<font color='#FFFF00'>");
			list = list.replace(/\^4/g, "<font color='#0000FF'>");
			list = list.replace(/\^5/g, "<font color='#00FFFF'>");
			list = list.replace(/\^6/g, "<font color='#FF00FF'>");
			list = list.replace(/\^7/g, "<font color='#FFFFFF'>");
			//list = list + '<\/span>';
		}
		elCell.innerHTML = list;
	};
	var aSearchIpTableColums = [
			{ key:"ip", label:"IP", sortable:true, hidden: bHideNumericIps },
			{ key:"ip_txt", label:"IP Address", sortable:true },
			{ key:"player_ids", label:"Player IDs", formatter: formatList, hidden: bHideIds },
			{ key:"player_names", label:"Player Names", formatter: formatNameList }
		];
	var oSearchIpSchema = {
			resultsList: 'data',
			fields: [
				{key:'ip', parser:'number'},
				{key:'ip_txt'},
				{key:'player_ids'},
				{key:'player_names'}
			],
			metaFields: {
				rows: 'rows'
			}
		};
	/* End of Search Panel Variables */
	
	
	

	var msgSearchError = function() {
		ri.alert("There was an error preforming the search.");
	};

	
	var handleSubmitName = function() { this.submit(); };
	var oSearchNameDlg = new YAHOO.widget.Dialog("search_name",
		{	width: "350px",
			visible: false,
			draggable: true,
			dragOnly: true,
			close: true,
			fixedcenter:true,
			underlay: "none",
			zIndex: 3,
			constraintoviewport: true,
			buttons: [ { text: "Search", handler: handleSubmitName, isDefault: true }, { text: "Close", handler: handleGenericCancel } ]
		} );
	oSearchNameDlg.validate = function() {
		var data = this.getData();
		if (data && data.name_text == "") {
			alert("Please enter some text to search for..");
			return false;
		} else {
			return true;
		}
	};
	oSearchNameDlg.callback.success = fNewSearchPanel;
	oSearchNameDlg.callback.failure = msgSearchError;
	oSearchNameDlg.render(document.body);



	var handleSubmitIp = function() { this.submit(); };
	var oSearchIpDlg = new YAHOO.widget.Dialog("search_ip",
		{	width: "275px",
			visible: false,
			draggable: true,
			dragOnly: true,
			close: true,
			fixedcenter:true,
			underlay: "none",
			zIndex: 3,
			constraintoviewport: true,
			buttons: [ { text:"Search", handler: handleSubmitIp }, { text:"Close", handler: handleGenericCancel, isDefault: true } ]
		} );
	oSearchIpDlg.validate = function() {
		var data = this.getData();
		if (data && data.ip_text == "") {
			alert("Please enter something to search for..");
			return false;
		} else {
			return true;
		}
	};
	oSearchIpDlg.callback.success = fNewSearchPanel;
	oSearchIpDlg.callback.failure = msgSearchError;
	oSearchIpDlg.render(document.body);


	var oCurrentPlayers = new YAHOO.widget.Panel("current_players", {
	/*		width:"700px",
			height:"400px", */
			visible:false,
			draggable:true,
			dragOnly:true,
			close:true,
			underlay:"none",
			fixedcenter:true,
			constraintoviewport:true,
			zIndex: -1
		} );
	oCurrentPlayers.setBody("<div id='player_table'><\/div>");
	oCurrentPlayers.render(document.body);
	
	var aPlayerTableColumns = [
		{ key:"slot_num", label:"Slot", formatter:"number", sortable:true },
		{ key:"score", label:"Score", formatter:"number", sortable:true },
		{ key:"ping", label:"Ping", formatter:"number", sortable:true },
		{ key:"name", label:"Player Name", formatter: formatNameColors },
		{ key:"ip", label:"IP Address" },
		{ key:"qport", label:"q Port", formatter:"number", sortable:true },
		{ key:"rate", label:"Rate", formatter:"number", sortable:true }
	];

	var oPlayerDataSource = new YAHOO.util.DataSource( sUrlBase + '?players' );
	oPlayerDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
	oPlayerDataSource.responseSchema = {
		resultsList: 'data',
		fields: [
			{key:'slot_num', parser:'number'},
			{key:'score', parser:'number'},
			{key:'ping', parser:'number'},
			{key:'name'},
			{key:'ip', parser: long2ip },
			{key:'qport', parser:'number'},
			{key:'rate', parser:'number'}
		],
		metaFields: {
			rows: 'rows'
		}
	};

	var oPlayerTableConfigs = {
		sortedBy:{key:'slot_num',dir:'asc'},
		selectionMode: 'single'
	};
	
	var oPlayerTable = new YAHOO.widget.DataTable("player_table", aPlayerTableColumns, oPlayerDataSource, oPlayerTableConfigs);
	
	var PlayerDataCallback = {
		success: oPlayerTable.onDataReturnInitializeTable,
		failure: function() { alert("Error getting player list from database backend."); },
		scope: oPlayerTable
	};
	
	oPlayerDataSource.setInterval(3000, null, PlayerDataCallback);
	// If Possible: only poll backend if the playerlist panel is visible...


	YAHOO.util.Event.addListener("about", "click", oAboutPanel.show, oAboutPanel, true);
	YAHOO.util.Event.addListener("help_reference", "click", oHelpPanel.show, oHelpPanel, true);
	YAHOO.util.Event.addListener("options", "click", oOptionsPanel.show, oOptionsPanel, true);
	YAHOO.util.Event.addListener("serverpassword", "click", oServerRconPwDlg.show, oServerRconPwDlg, true);
	YAHOO.util.Event.addListener("currentplayers", "click", oCurrentPlayers.show, oCurrentPlayers, true);
	YAHOO.util.Event.addListener("mainstatus", "click", oStatusPanel.show, oStatusPanel, true);
	YAHOO.util.Event.addListener("serverconfig", "click", oServerCfgDlg.show, oServerCfgDlg, true);
	YAHOO.util.Event.addListener("searchname", "click", oSearchNameDlg.show, oSearchNameDlg, true);
	YAHOO.util.Event.addListener("searchip", "click", oSearchIpDlg.show, oSearchIpDlg, true);
	
	YAHOO.util.Event.addListener("colornames", "click", fColorNames);
	YAHOO.util.Event.addListener("convertduration", "click", fConvertDuration);
	YAHOO.util.Event.addListener("showplayerids", "click", fShowIds);
	YAHOO.util.Event.addListener("shownumericips", "click", fShowNumericIps);
	
	
	var key1 = new YAHOO.util.KeyListener(document, { alt:true, keys:90}, {fn:oSearchNameDlg.show, scope:oSearchNameDlg, correctScope:true});
	var key2 = new YAHOO.util.KeyListener(document, { alt:true, keys:88}, {fn:oSearchIpDlg.show, scope:oSearchIpDlg, correctScope:true});
	var key3 = new YAHOO.util.KeyListener(document, { alt:true, keys:67}, {fn:oCurrentPlayers.show, scope:oCurrentPlayers, correctScope:true});

	key1.enable();
	key2.enable();
	key3.enable();
};



/*	Initialize and render when the DOM is ready to be scripted.	*/
YAHOO.util.Event.onDOMReady( ri.init );

//-->
</script>
		

</head>

<body class="yui-skin-sam">

	<div id="about_info" title="About">
		<div class="hd">About Remote Interface</div>
		<div class="bd">
			<p class="about_title">Urban Terror 4.1 Remote Interface.</p><br>
			<p class="about_version">Version: 0.1 &nbsp;-&nbsp; July 2009</p>
			<p style="margin-left:2em;">Author: Jeff Genovy (jgen)</p>
		</div>
	</div>

	<div id="help_panel" title="Help">
		<div class="hd">Help</div>
		<div class="bd">
			<h3>Welcome to the Remote Interface</h3>
			<p>This web application is a front end to the RCON monitoring script.</p>
			<p>While it is still under development, most features available work fine.</p>
			<p>Please note:<br>
			You cannot change the rcon password or server configuration<br>
			Go ahead and try it, but the changes will not apply</p>
			<p>Wildcards are supported for all searches:</p>
			<p>
			<table border="0" cellpadding="4" style="margin-left:2em;">
				<tbody>
					<tr>
						<td><span style="color:#408080;font-weight:bold;font-family: Arial;font-size:16pt">*</span></td>
						<td>Matches any character, zero or more times</td>
					</tr>
					<tr>
						<td><span style="color:#408080;font-weight:bold;font-family: Arial;font-size:16pt">?</span></td>
						<td>Matches exactly one character</td>
					</tr>
				</tbody>
			</table>
			</p>
		</div>
	</div>
	
	<div id="options_panel" title="Options">
		<div class="hd">Options</div>
		<div class="bd">
			<fieldset id="option_container" class="option_buttons">
				<legend>Options</legend>
				<div>
					<input type="checkbox" id="colornames" value="colornames">
					<label for="colornames">Colorize Names</label><br>
					<input type="checkbox" id="convertduration" value="convertduration">
					<label for="convertduration">Convert Duration</label><br>
				</div>
				<div>
					<input type="checkbox" id="showplayerids" value="showplayerids">
					<label for="showplayerids">Show Player IDs</label><br>
					<input type="checkbox" id="shownumericips" value="shownumericips">
					<label for="shownumericips">Show Numeric IPs</label>
				</div>
			</fieldset>
		</div>
	</div>
	
	<div id="current_players" title="Current Players">
		<div class="hd">Current Players</div>
		<div class="bd">
		</div>
	</div>
	
	<div id="server_rcon_pw" title="Server RCON Password">
		<div class="hd">Server RCON Password</div>
		<div class="bd">
			<form id="srv_rcon_password" method="POST" action="interface.php">
				<input type="hidden" name="server_pw">
				<label for="srv_rcon_pw">RCON Password:</label><input type="text" maxlength="32" size="20" name="pw" id="srv_rcon_pw" alt="Server Rcon Password" title="Server Rcon Password"><br>
			</form>
		</div>
	</div>
	
	<div id="server_config">
		<div class="hd">Configure Server Settings</div>
		<div class="bd">
			<form id="srv_config" method="POST" action="interface.php" class="config">
				<fieldset>
					<legend class="config">Server Address</legend>
					<input type="hidden" name="server_config">
					<label for="srv_ip_address">IP:</label><input type="text" maxlength="18" size="18" name="ip" id="srv_ip_address" alt="Server IP Address" title="Server IP Address"><br>
					<label for="srv_port">Port:</label><input type="text" name="port" maxlength="8" size="10" id="srv_port" alt="Server Port - Default is 27960" title="Server Port - Default is 27960">
				</fieldset>
				<fieldset>
					<legend class="config">Timeout Configuration</legend>
					<label for="srv_timeout">Delay time:</label><input type="text" name="timeout_delay" maxlength="4" size="5" id="srv_timeout" alt="How long to wait for a response from the server" title="How long to wait for a response from the server"><br>
					<label for="srv_timeout_wait">Wait time:</label><input type="text" name="timeout_wait" maxlength="4" size="5" id="srv_timeout_wait" alt="How long to wait after a timeout occurs" title="How long to wait after a timeout occurs"><br>
				</fieldset>
			</form>
		</div>	
	</div>
	
	<div id="search_name" title="Search by Name">
		<div class="hd">Search By Name</div>
		<div class="bd">
			<form id="search_by_name" method="POST" action="interface.php">
				<input type="hidden" name="search_name">
				<label for="search_name_text">Player Name:</label><input type="text" maxlength="32" size="28" name="name_text" id="search_name_text" alt="Player name" title="Player name"> 
			</form>
		</div>
	</div>

	<div id="search_ip" title="Search by IP">
		<div class="hd">Search By IP</div>
		<div class="bd">
			<form id="search_by_ip" method="POST" action="interface.php">
				<input type="hidden" name="search_ip">
				<label for="search_ip_text">IP Address:</label><input type="text" maxlength="18" size="18" name="ip_text" id="search_ip_text" alt="Player IP Address" title="Player IP Address">
			</form>
		</div>
	</div>

	<div id="search_results_container"></div>

</body>
</html>
